home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / Window.java < prev   
Encoding:
Java Source  |  1999-05-28  |  31.6 KB  |  1,070 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Window.java    1.106 98/10/27
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.peer.WindowPeer;
  17. import java.awt.event.*;
  18. import java.util.Vector;
  19. import java.util.Locale;
  20. import java.io.Serializable;
  21. import java.io.ObjectOutputStream;
  22. import java.io.ObjectInputStream;
  23. import java.io.IOException;
  24. import java.io.OptionalDataException;
  25. import java.awt.im.InputContext;
  26. import java.util.ResourceBundle;
  27. import java.lang.ref.WeakReference;
  28. import java.lang.reflect.InvocationTargetException;
  29. import java.security.AccessController;
  30. import sun.security.action.GetPropertyAction;
  31.  
  32. /**
  33.  * A <code>Window</code> object is a top-level window with no borders and no
  34.  * menubar.  
  35.  * The default layout for a window is <code>BorderLayout</code>.
  36.  * <p>
  37.  * A window must have either a frame, dialog, or another window defined as its
  38.  * owner when it's constructed. 
  39.  * <p>
  40.  * Windows are capable of generating the following window events:
  41.  * WindowOpened, WindowClosed.
  42.  *
  43.  * @version     1.106, 10/27/98
  44.  * @author     Sami Shaio
  45.  * @author     Arthur van Hoff
  46.  * @see WindowEvent
  47.  * @see #addWindowListener
  48.  * @see java.awt.BorderLayout
  49.  * @since       JDK1.0
  50.  */
  51. public class Window extends Container {
  52.  
  53.     /**
  54.      * This represents the warning message that is
  55.      * to be displayed in a non secure window. ie :
  56.      * a window that has a security manager installed for
  57.      * which calling SecurityManager.checkTopLevelWindow()
  58.      * is false.  This message can be displayed anywhere in
  59.      * the window.
  60.      *
  61.      * @serial
  62.      * @see getWarningString()
  63.      */
  64.     String      warningString;
  65.  
  66.     static final int OPENED = 0x01;
  67.  
  68.     /**
  69.      * An Integer value representing the Window State.
  70.      *
  71.      * @serial
  72.      * @since JDK1.2
  73.      * @see show()
  74.      */
  75.     int state;
  76.  
  77.     /**
  78.      * A vector containing all the windows this
  79.      * window currently owns.
  80.      * @since JDK1.2
  81.      * @see getOwnedWindows()
  82.      */
  83.     transient Vector ownedWindowList;
  84.     private transient WeakReference weakThis;
  85.  
  86.     transient WindowListener windowListener;
  87.     private transient boolean active = false;   // == true when Window receives WINDOW_ACTIVATED event
  88.                                                 // == false when Window receives WINDOW_DEACTIVATED event
  89.     
  90.     transient InputContext inputContext;
  91.  
  92.     /**
  93.      * The Focus for the Window in question, and its components.
  94.      *
  95.      * @serial
  96.      * @since JDK1.2
  97.      * @See java.awt.FocusManager
  98.      */
  99.     private FocusManager focusMgr;
  100.  
  101.     private static final String base = "win";
  102.     private static int nameCounter = 0;
  103.  
  104.     /*
  105.      * JDK 1.1 serialVersionUID 
  106.      */
  107.     private static final long serialVersionUID = 4497834738069338734L;
  108.  
  109.  
  110.     static {
  111.         /* ensure that the necessary native libraries are loaded */
  112.     Toolkit.loadLibraries();
  113.     initIDs();
  114.     }
  115.  
  116.     /**
  117.      * Initialize JNI field and method IDs for fields that may be
  118.        accessed from C.
  119.      */
  120.     private static native void initIDs();
  121.  
  122.     /**
  123.      * Constructs a new window.
  124.      * 
  125.      * <p>First, if there is a security manager, its 
  126.      * <code>checkTopLevelWindow</code> 
  127.      * method is called with <code>this</code> 
  128.      * as its argument
  129.      * to see if it's ok to display the window without a warning banner. 
  130.      * If the default implementation of <code>checkTopLevelWindow</code> 
  131.      * is used (that is, that method is not overriden), then this results in
  132.      * a call to the security manager's <code>checkPermission</code> method with an
  133.      * <code>AWTPermission("showWindowWithoutWarningBanner")<code>
  134.      * permission. It that method raises a SecurityException, 
  135.      * <code>checkTopLevelWindow</code> returns false, otherwise it
  136.      * returns true. If it returns false, a warning banner is created.
  137.      *
  138.      * @see java.lang.SecurityManager#checkTopLevelWindow
  139.      */
  140.     Window() {
  141.     setWarningString();
  142.     this.focusMgr = new FocusManager(this);
  143.     this.visible = false;
  144.     this.inputContext = InputContext.getInstance();
  145.     }
  146.  
  147.     /**
  148.      * Constructs a new invisible window.
  149.      * <p>
  150.      * The window is not initially visible. Call the <code>show</code> 
  151.      * method to cause the window to become visible.
  152.      * <p>
  153.      * If there is a security manager, this method first calls 
  154.      * the security manager's <code>checkTopLevelWindow</code> 
  155.      * method with <code>this</code> 
  156.      * as its argument to determine whether or not the window 
  157.      * must be displayed with a warning banner. 
  158.      * 
  159.      * @param     owner   the main application frame.
  160.      * @exception java.lang.IllegalArgumentException if <code>owner</code> 
  161.      *            is <code>null</code>
  162.      * @see       java.awt.Window#show
  163.      * @see       java.awt.Component#setSize
  164.      * @see       java.lang.SecurityManager#checkTopLevelWindow
  165.      */
  166.     public Window(Frame owner) {
  167.     this();
  168.     ownedInit(owner);
  169.     }
  170.  
  171.     /**
  172.      * Constructs a new invisible window with the specified
  173.      * window as its owner.
  174.      * <p>
  175.      * If there is a security manager, this method first calls 
  176.      * the security manager's <code>checkTopLevelWindow</code> 
  177.      * method with <code>this</code> 
  178.      * as its argument to determine whether or not the window 
  179.      * must be displayed with a warning banner. 
  180.      * 
  181.      * @param     owner   the window to act as owner
  182.      * @exception java.lang.IllegalArgumentException if <code>owner</code> 
  183.      *            is <code>null</code>
  184.      * @see       java.lang.SecurityManager#checkTopLevelWindow
  185.      * @since     JDK1.2
  186.      */
  187.     public Window(Window owner) {
  188.     this();
  189.     ownedInit(owner);
  190.     }
  191.  
  192.     private void ownedInit(Window owner) {
  193.     if (owner == null) {
  194.         throw new IllegalArgumentException("null owner window");
  195.     }    
  196.     this.parent = owner;
  197.     this.weakThis = new WeakReference(this);
  198.     owner.addOwnedWindow(weakThis);
  199.     setLayout(new BorderLayout());
  200.     }
  201.  
  202.     /**
  203.      * Disposes of the input methods and context, and removes the WeakReference
  204.      * which formerly pointed to this Window from the parent's owned Window
  205.      * list.
  206.      */
  207.     protected void finalize() throws Throwable {
  208.         inputContext.dispose();
  209.     if (parent != null) {
  210.         ((Window)parent).removeOwnedWindow(weakThis);
  211.     }
  212.     super.finalize();
  213.     }
  214.  
  215.     /**
  216.      * Construct a name for this component.  Called by getName() when the
  217.      * name is null.
  218.      */
  219.     String constructComponentName() {
  220.         synchronized (getClass()) {
  221.         return base + nameCounter++;
  222.     }
  223.     }
  224.  
  225.     /**
  226.      * Makes this Window displayable by creating the connection to its
  227.      * native screen resource.  
  228.      * This method is called internally by the toolkit and should
  229.      * not be called directly by programs.
  230.      * @see Component#isDisplayable
  231.      * @see Container#removeNotify
  232.      * @since JDK1.0
  233.      */
  234.     public void addNotify() {
  235.     synchronized (getTreeLock()) {
  236.         if (peer == null)
  237.         peer = getToolkit().createWindow(this);
  238.         super.addNotify();
  239.     }
  240.     }
  241.  
  242.     /**
  243.      * Causes this Window to be sized to fit the preferred size
  244.      * and layouts of its subcomponents.  If the window and/or its owner
  245.      * are not yet displayable, both are made displayable before
  246.      * calculating the preferred size.  The Window will be validated
  247.      * after the preferredSize is calculated.
  248.      * @see Component#isDisplayable
  249.      */
  250.     public void pack() {
  251.     Container parent = this.parent;
  252.     if (parent != null && parent.getPeer() == null) {
  253.         parent.addNotify();
  254.     }
  255.     if (peer == null) {
  256.         addNotify();
  257.     }
  258.     setSize(getPreferredSize());
  259.     isPacked = true;
  260.  
  261.     validate();
  262.     }
  263.  
  264.     /**
  265.      * Makes the Window visible. If the Window and/or its owner
  266.      * are not yet displayable, both are made displayable.  The 
  267.      * Window will be validated prior to being made visible.  
  268.      * If the Window is already visible, this will bring the Window 
  269.      * to the front.
  270.      * @see       java.awt.Component#isDisplayable
  271.      * @see       java.awt.Window#toFront
  272.      * @see       java.awt.Component#setVisible
  273.      */
  274.     public void show() {
  275.         Container parent = this.parent;
  276.     if (parent != null && parent.getPeer() == null) {
  277.         parent.addNotify();
  278.     }
  279.     if (peer == null) {
  280.         addNotify();
  281.     }
  282.     validate();
  283.  
  284.     if (visible) {
  285.         toFront();
  286.     } else {
  287.         super.show();
  288.     }
  289.         
  290.         // If first time shown, generate WindowOpened event
  291.         if ((state & OPENED) == 0) {
  292.             postWindowEvent(WindowEvent.WINDOW_OPENED);
  293.             state |= OPENED;
  294.         }
  295.     }
  296.  
  297.     synchronized void postWindowEvent(int id) {
  298.         if (windowListener != null || 
  299.             (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0) {
  300.             WindowEvent e = new WindowEvent(this, id);
  301.             Toolkit.getEventQueue().postEvent(e);
  302.         }
  303.     }
  304.         
  305.     /**
  306.      * Releases all of the native screen resources used by this Window and
  307.      * its subcomponents. That is, the resources for the Window, all of its
  308.      * contained children, and all of its owned Windows will be destroyed,
  309.      * and any memory they consume returned to the OS. The Window and all of
  310.      * its subcomponents will be marked as undisplayable.
  311.      * <p>
  312.      * The Window and its subcomponents can be made displayable again
  313.      * by rebuilding the native resources with a subsequent call to
  314.      * <code>pack</code> or <code>show</code>. The states of the recreated
  315.      * Window and its subcomponents will be identical to the states of these
  316.      * objects at the point where the Window was disposed (not accounting for
  317.      * additional modifcations between those actions).
  318.      * </p>
  319.      * @see Component#isDisplayable
  320.      * @see Window#getOwnedWindows
  321.      * @see Window#pack
  322.      * @see Window#show
  323.      */
  324.     public void dispose() {
  325.         class DisposeAction implements Runnable {
  326.         public void run() {
  327.             if (ownedWindowList != null) {
  328.             synchronized (ownedWindowList) {
  329.                 for (int i = 0; i < ownedWindowList.size(); i++) {
  330.                 Window child = (Window) (((WeakReference)
  331.                     (ownedWindowList.elementAt(i))).get());
  332.                 if (child != null) {
  333.                     child.dispose();
  334.                 }
  335.             }
  336.             }
  337.         }
  338.         hide();
  339.         removeNotify();
  340.         }
  341.     }
  342.     
  343.     DisposeAction action = new DisposeAction();
  344.     if (EventQueue.isDispatchThread()) {
  345.         action.run();
  346.     }
  347.     else {
  348.         try {
  349.             EventQueue.invokeAndWait(action);
  350.         }
  351.         catch (InterruptedException e) {
  352.             System.err.println("Disposal was interrupted:");
  353.         e.printStackTrace();
  354.         }
  355.         catch (InvocationTargetException e) {
  356.             System.err.println("Exception during disposal:");
  357.         e.printStackTrace();
  358.         }
  359.     }
  360.     // Execute outside the Runnable because postWindowEvent is
  361.     // synchronized on (this). We don't need to synchronize the call
  362.     // on the EventQueue anyways.
  363.     postWindowEvent(WindowEvent.WINDOW_CLOSED);
  364.     }
  365.  
  366.     /**
  367.      * Brings this window to the front.
  368.      * Places this window at the top of the stacking order and
  369.      * shows it in front of any other windows.
  370.      * @see       java.awt.Window#toBack
  371.      */
  372.     public void toFront() {
  373.         WindowPeer peer = (WindowPeer)this.peer;
  374.     if (peer != null) {
  375.         peer.toFront();
  376.     }
  377.     }
  378.  
  379.     /**
  380.      * Sends this window to the back.
  381.      * Places this window at the bottom of the stacking order and
  382.      * makes the corresponding adjustment to other visible windows.
  383.      * @see       java.awt.Window#toFront
  384.      */
  385.     public void toBack() {
  386.         WindowPeer peer = (WindowPeer)this.peer;
  387.     if (peer != null) {
  388.         peer.toBack();
  389.     }
  390.     }
  391.  
  392.     /**
  393.      * Returns the toolkit of this frame.
  394.      * @return    the toolkit of this window.
  395.      * @see       java.awt.Toolkit
  396.      * @see       java.awt.Toolkit#getDefaultToolkit()
  397.      * @see       java.awt.Component#getToolkit()
  398.      */
  399.     public Toolkit getToolkit() {
  400.     return Toolkit.getDefaultToolkit();
  401.     }
  402.  
  403.     /**
  404.      * Gets the warning string that is displayed with this window. 
  405.      * If this window is insecure, the warning string is displayed 
  406.      * somewhere in the visible area of the window. A window is 
  407.      * insecure if there is a security manager, and the security 
  408.      * manager's <code>checkTopLevelWindow</code> method returns 
  409.      * <code>false</code> when this window is passed to it as an
  410.      * argument.
  411.      * <p>
  412.      * If the window is secure, then <code>getWarningString</code>
  413.      * returns <code>null</code>. If the window is insecure, this
  414.      * method checks for the system property 
  415.      * <code>awt.appletWarning</code> 
  416.      * and returns the string value of that property. 
  417.      * @return    the warning string for this window.
  418.      * @see       java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
  419.      */
  420.     public final String getWarningString() {
  421.     return warningString;
  422.     }
  423.  
  424.     private void setWarningString() {
  425.     warningString = null;
  426.     SecurityManager sm = System.getSecurityManager();
  427.     if (sm != null) {
  428.         if (!sm.checkTopLevelWindow(this)) {
  429.         // make sure the privileged action is only
  430.         // for getting the property! We don't want the
  431.         // above checkTopLevelWindow call to always succeed!
  432.         warningString = (String) AccessController.doPrivileged(
  433.               new GetPropertyAction("awt.appletWarning",
  434.                         "Warning: Applet Window"));
  435.         }
  436.     }
  437.     }
  438.  
  439.     /** 
  440.      * Gets the <code>Locale</code> object that is associated 
  441.      * with this window, if the locale has been set.
  442.      * If no locale has been set, then the default locale 
  443.      * is returned.
  444.      * @return    the locale that is set for this window.
  445.      * @see       java.util.Locale
  446.      * @since     JDK1.1
  447.      */
  448.  
  449.     public Locale getLocale() {
  450.       if (this.locale == null) {
  451.     return Locale.getDefault();
  452.       }
  453.       return this.locale;
  454.     }
  455.  
  456.     /**
  457.      * Gets the input context for this window. A window always has an input context,
  458.      * which is shared by subcomponents unless they create and set their own.
  459.      * @see Component#getInputContext
  460.      * @since JDK1.2
  461.      */
  462.  
  463.     public InputContext getInputContext() {
  464.         return inputContext;
  465.     }
  466.  
  467.     /**
  468.      * Returns the owner of this window.
  469.      */
  470.     public Window getOwner() {
  471.         return (Window)parent;
  472.     }
  473.  
  474.     /**
  475.      * Return an array containing all the windows this
  476.      * window currently owns.
  477.      * @since JDK1.2
  478.      */
  479.     public Window[] getOwnedWindows() {
  480.         Window realCopy[];
  481.         if (ownedWindowList != null) {
  482.             synchronized(ownedWindowList) {
  483.             // Recall that ownedWindowList is actually a Vector of
  484.             // WeakReferences and calling get() on one of these references
  485.             // may return null. Make two arrays-- one the size of the
  486.             // Vector (fullCopy with size fullSize), and one the size of 
  487.             // all non-null get()s (realCopy with size realSize).
  488.                 int fullSize = ownedWindowList.size();
  489.                 int realSize = 0;
  490.                 Window fullCopy[] = new Window[fullSize];
  491.  
  492.                 for (int i = 0; i < fullSize; i++) {
  493.                     fullCopy[realSize] = (Window) (((WeakReference)
  494.                         (ownedWindowList.elementAt(i))).get());
  495.  
  496.                     if (fullCopy[realSize] != null) {
  497.                         realSize++;
  498.                     }
  499.                 }
  500.  
  501.         if (fullSize != realSize) {
  502.             realCopy = new Frame[realSize];
  503.             System.arraycopy(fullCopy, 0, realCopy, 0, realSize);
  504.         } else {
  505.             realCopy = fullCopy;
  506.         }
  507.         }
  508.     } else {
  509.         realCopy = new Window[0];
  510.     }
  511.         return realCopy;
  512.     }
  513.  
  514.     /**
  515.      * Adds the specified window listener to receive window events from
  516.      * this window.
  517.      * If l is null, no exception is thrown and no action is performed.
  518.      *
  519.      * @param     l the window listener
  520.      */ 
  521.     public synchronized void addWindowListener(WindowListener l) {
  522.     if (l == null) {
  523.         return;
  524.     }
  525.         windowListener = AWTEventMulticaster.add(windowListener, l);
  526.         newEventsOnly = true;
  527.     }
  528.  
  529.     /**
  530.      * Removes the specified window listener so that it no longer
  531.      * receives window events from this window.
  532.      * If l is null, no exception is thrown and no action is performed.
  533.      *
  534.      * @param     l the window listener
  535.      */ 
  536.     public synchronized void removeWindowListener(WindowListener l) {
  537.     if (l == null) {
  538.         return;
  539.     }
  540.         windowListener = AWTEventMulticaster.remove(windowListener, l);
  541.     }
  542.  
  543.     // REMIND: remove when filtering is handled at lower level
  544.     boolean eventEnabled(AWTEvent e) {
  545.         switch(e.id) {
  546.           case WindowEvent.WINDOW_OPENED:
  547.           case WindowEvent.WINDOW_CLOSING:
  548.           case WindowEvent.WINDOW_CLOSED:
  549.           case WindowEvent.WINDOW_ICONIFIED:
  550.           case WindowEvent.WINDOW_DEICONIFIED:
  551.           case WindowEvent.WINDOW_ACTIVATED:
  552.           case WindowEvent.WINDOW_DEACTIVATED:
  553.             if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
  554.                 windowListener != null) {
  555.                 return true;
  556.             }
  557.             return false;
  558.           default:
  559.             break;
  560.         }
  561.         return super.eventEnabled(e);
  562.     }
  563.  
  564.     boolean isActive() {
  565.     return active;
  566.     }
  567.  
  568.     /**
  569.      * Processes events on this window. If the event is an WindowEvent,
  570.      * it invokes the processWindowEvent method, else it invokes its
  571.      * superclass's processEvent.
  572.      * @param e the event
  573.      */
  574.     protected void processEvent(AWTEvent e) {
  575.         if (e instanceof WindowEvent) {
  576.             processWindowEvent((WindowEvent)e);
  577.             return;
  578.         }
  579.     super.processEvent(e);
  580.     }
  581.  
  582.     /** 
  583.      * Processes window events occurring on this window by
  584.      * dispatching them to any registered WindowListener objects.
  585.      * NOTE: This method will not be called unless window events
  586.      * are enabled for this component; this happens when one of the
  587.      * following occurs:
  588.      * a) A WindowListener object is registered via addWindowListener()
  589.      * b) Window events are enabled via enableEvents()
  590.      * @see Component#enableEvents
  591.      * @param e the window event
  592.      */  
  593.     protected void processWindowEvent(WindowEvent e) {
  594.         if (windowListener != null) {
  595.             switch(e.getID()) {
  596.               case WindowEvent.WINDOW_OPENED:
  597.                 windowListener.windowOpened(e);
  598.                 break;
  599.               case WindowEvent.WINDOW_CLOSING:
  600.                 windowListener.windowClosing(e);
  601.                 break;
  602.               case WindowEvent.WINDOW_CLOSED:
  603.                 windowListener.windowClosed(e);
  604.                 break;
  605.               case WindowEvent.WINDOW_ICONIFIED:
  606.                 windowListener.windowIconified(e);
  607.                 break;
  608.               case WindowEvent.WINDOW_DEICONIFIED:
  609.                 windowListener.windowDeiconified(e);
  610.                 break;
  611.               case WindowEvent.WINDOW_ACTIVATED:
  612.                 windowListener.windowActivated(e);
  613.                 break;
  614.               case WindowEvent.WINDOW_DEACTIVATED:
  615.                 windowListener.windowDeactivated(e);
  616.                 break;
  617.               default:
  618.                 break;
  619.             }
  620.         }
  621.     }
  622.  
  623.     void preProcessKeyEvent(KeyEvent e) {
  624.         // Dump the list of child windows to System.out.
  625.         if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
  626.             e.isControlDown() && e.isShiftDown() && 
  627.             e.getID() == KeyEvent.KEY_PRESSED) {
  628.             list(System.out, 0);
  629.         }
  630.     }
  631.  
  632.     void postProcessKeyEvent(KeyEvent e) {
  633.         WindowPeer    peer = (WindowPeer)this.peer;
  634.         if (peer == null)
  635.             return;
  636.  
  637.       switch(peer.handleFocusTraversalEvent(e)) {
  638.     case WindowPeer.IGNORE_EVENT:
  639.     default:
  640.         break;
  641.     case WindowPeer.CONSUME_EVENT:
  642.         e.consume();
  643.         break;
  644.     case WindowPeer.FOCUS_NEXT:
  645.         if (focusMgr.focusNext())
  646.         e.consume();
  647.         break;
  648.     case WindowPeer.FOCUS_PREVIOUS:
  649.         if (focusMgr.focusPrevious())
  650.         e.consume();
  651.         break;
  652.     }
  653.  
  654.     return;
  655.     }
  656.  
  657.     void setFocusOwner(Component c) {
  658.     focusMgr.setFocusOwner(c);
  659.     }
  660.  
  661.     void transferFocus(Component base) {
  662.     nextFocus(base);
  663.     }
  664.  
  665.     /**
  666.      * Returns the child component of this Window which has focus if and 
  667.      * only if this Window is active.
  668.      * @return the component with focus, or null if no children have focus
  669.      * assigned to them.
  670.      */
  671.     public Component getFocusOwner() {
  672.         if (active)
  673.             return focusMgr.getFocusOwner();
  674.         else
  675.             return null;
  676.     }
  677.  
  678.     /**
  679.      * @deprecated As of JDK version 1.1,
  680.      * replaced by <code>transferFocus(Component)</code>.
  681.      */
  682.     void nextFocus(Component base) {
  683.     focusMgr.focusNext(base);
  684.     }
  685.  
  686.     /*
  687.      * Dispatches an event to this window or one of its sub components.
  688.      * @param e the event
  689.      */
  690.     void dispatchEventImpl(AWTEvent e) {
  691.         switch(e.getID()) {
  692.           case FocusEvent.FOCUS_GAINED:
  693.             setFocusOwner(this);
  694.             break;
  695.           case ComponentEvent.COMPONENT_RESIZED:
  696.             invalidate();
  697.             validate();
  698.             repaint();
  699.             break;
  700.           case WindowEvent.WINDOW_ACTIVATED:
  701.             active = true;
  702. /*
  703.   Calling this messes up focus on Solaris
  704.  
  705.             focusMgr.activateFocus();
  706. */
  707.             break;
  708.           case WindowEvent.WINDOW_DEACTIVATED:
  709.             active = false;
  710.             break;
  711.           default:
  712.             break;
  713.         }
  714.         super.dispatchEventImpl(e);
  715.     }
  716.  
  717.     /**
  718.      * @deprecated As of JDK version 1.1
  719.      * replaced by <code>dispatchEvent(AWTEvent)</code>.
  720.      */
  721.     public boolean postEvent(Event e) {
  722.         if (handleEvent(e)) {
  723.             e.consume();
  724.             return true;
  725.         }
  726.         return false;
  727.     }
  728.  
  729.     /**
  730.      * Checks if this Window is showing on screen.
  731.      * @see java.awt.Component#setVisible(boolean)
  732.     */
  733.     public boolean isShowing() {
  734.     return visible;
  735.     }
  736.  
  737.     /**
  738.      * Apply the settings in the given ResourceBundle to this Window.
  739.      * Currently, this applies the ResourceBundle's ComponentOrientation
  740.      * to this Window and all components contained within it.
  741.      *
  742.      * @see java.awt.ComponentOrientation
  743.      * @since JDK1.2
  744.      */
  745.     public void applyResourceBundle(ResourceBundle rb) {
  746.         // A package-visible utility on Container does all the work
  747.         applyOrientation(ComponentOrientation.getOrientation(rb));
  748.     }
  749.     
  750.     /**
  751.      * Load the ResourceBundle with the given name using the default locale
  752.      * and apply its settings to this window.
  753.      * Currently, this applies the ResourceBundle's ComponentOrientation
  754.      * to this Window and all components contained within it.
  755.      *
  756.      * @see java.awt.ComponentOrientation
  757.      * @since JDK1.2
  758.      */
  759.     public void applyResourceBundle(String rbName) {
  760.         applyResourceBundle(ResourceBundle.getBundle(rbName));
  761.     }
  762.  
  763.  
  764.  
  765.    /* 
  766.     * Support for tracking all windows owned by this window
  767.     */
  768.     void addOwnedWindow(WeakReference weakWindow) {
  769.         if (weakWindow != null) {
  770.         if (ownedWindowList == null) {
  771.             ownedWindowList = new Vector();
  772.         }
  773.  
  774.         // this if statement should really be an assert, but we don't
  775.         // have asserts...
  776.         if (!ownedWindowList.contains(weakWindow)) {
  777.             ownedWindowList.addElement(weakWindow);
  778.         }
  779.     }
  780.     }
  781.  
  782.     void removeOwnedWindow(WeakReference weakWindow) {
  783.         if (weakWindow != null && ownedWindowList != null) {
  784.         ownedWindowList.removeElement(weakWindow);
  785.     }
  786.     }
  787.  
  788.     void connectOwnedWindow(Window child) {
  789.         WeakReference weakChild = new WeakReference(child);
  790.     child.weakThis = weakChild;
  791.     child.parent = this;
  792.     addOwnedWindow(weakChild);
  793.     }
  794.  
  795.     /**
  796.      * The window serialized data version.
  797.      *
  798.      * @serial
  799.      */
  800.     private int windowSerializedDataVersion = 1;
  801.  
  802.     /**
  803.      * Writes default serializable fields to stream.  Writes
  804.      * a list of serializable ItemListener(s) as optional data.
  805.      * The non-serializable ItemListener(s) are detected and
  806.      * no attempt is made to serialize them. Write a list of
  807.      * child Windows as optional data.
  808.      *
  809.      * @serialData Null terminated sequence of 0 or more pairs.
  810.      *             The pair consists of a String and Object.
  811.      *             The String indicates the type of object and
  812.      *             is one of the following :
  813.      *             itemListenerK indicating an ItemListener object.
  814.      * @serialData Null terminated sequence of 0 or more pairs.
  815.      *             The pair consists of a String and Object.
  816.      *             The String indicates the type of object and
  817.      *             is one of the following :
  818.      *             ownedWindowK indicating a child Window object.
  819.      *
  820.      * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  821.      * @see java.awt.Component.itemListenerK
  822.      * @see java.awt.Component.ownedWindowK
  823.      */
  824.     private void writeObject(ObjectOutputStream s)
  825.       throws IOException 
  826.     {
  827.       s.defaultWriteObject();
  828.  
  829.       AWTEventMulticaster.save(s, windowListenerK, windowListener);
  830.       s.writeObject(null);
  831.  
  832.       if (ownedWindowList != null) {
  833.       synchronized (ownedWindowList) {
  834.           for (int i = 0; i < ownedWindowList.size(); i++) {
  835.           Window child = (Window) (((WeakReference)
  836.               (ownedWindowList.elementAt(i))).get());
  837.           if (child != null) {
  838.               s.writeObject(ownedWindowK);
  839.               s.writeObject(child);
  840.           }
  841.           }
  842.       }
  843.       }
  844.       s.writeObject(null);
  845.     }
  846.  
  847.     /**
  848.      * Read the default ObjectInputStream, a possibly null listener to
  849.      * receive item events fired by the Window, and a possibly null
  850.      * list of child Windows.
  851.      * Unrecognised keys or values will be Ignored.
  852.      *
  853.      * @see removeActionListener()
  854.      * @see addActionListener()
  855.      */
  856.     private void readObject(ObjectInputStream s)
  857.       throws ClassNotFoundException, IOException 
  858.     {
  859.       s.defaultReadObject();
  860.  
  861.       Object keyOrNull;
  862.       while(null != (keyOrNull = s.readObject())) {
  863.       String key = ((String)keyOrNull).intern();
  864.  
  865.       if (windowListenerK == key) 
  866.           addWindowListener((WindowListener)(s.readObject()));
  867.  
  868.       else // skip value for unrecognized key
  869.           s.readObject();
  870.       }
  871.  
  872.       try {
  873.       while (null != (keyOrNull = s.readObject())) {
  874.           String key = ((String)keyOrNull).intern();
  875.  
  876.           if (ownedWindowK == key)
  877.           connectOwnedWindow((Window) s.readObject());
  878.  
  879.           else // skip value for unrecognized key
  880.           s.readObject();
  881.       }
  882.       }
  883.       catch (OptionalDataException e) {
  884.       // 1.1 serialized form
  885.       // ownedWindowList will be updated by Frame.readObject
  886.       }
  887.  
  888.       setWarningString();
  889.       this.inputContext = InputContext.getInstance();
  890.     }
  891.  
  892. } // class Window
  893.  
  894.  
  895. class FocusManager implements java.io.Serializable {
  896.     Container focusRoot;
  897.     Component focusOwner;
  898.  
  899.     /*
  900.      * JDK 1.1 serialVersionUID 
  901.      */
  902.     static final long serialVersionUID = 2491878825643557906L;
  903.  
  904.     FocusManager(Container cont) {
  905.     focusRoot = cont;
  906.     }
  907.  
  908.     /* Re-activate the last component with focus if it is still
  909.      * visible and active.
  910.      * If no component had focus yet, assign it to first component
  911.      * capable of receiving it (visible, active, focusable).
  912.      * If no visible, active, focusable components are present,
  913.      * assign focus to the focus root.
  914.      */
  915.     void activateFocus() {
  916.         boolean assigned = false;
  917.         if (focusOwner != null) {
  918.             if ((assigned = assignFocus(focusOwner, false)) != true) {
  919.                 assigned = focusNext(focusOwner);
  920.             }
  921.         } else {
  922.             // assign to first component capable of taking it
  923.             assigned = focusForward(focusRoot);
  924.         }
  925.         if (!assigned) {
  926.             focusRoot.requestFocus(); 
  927.         }
  928.     }                
  929.                 
  930.      
  931.     synchronized void setFocusOwner(Component c) {
  932.         //System.out.println("FocusManager.setFocusOwner: "+c.name);
  933.         focusOwner = c;
  934.     }
  935.  
  936.     Component getFocusOwner() {
  937.        return focusOwner;
  938.     }
  939.     
  940.     boolean focusNext() {
  941.        return focusNext(focusOwner);
  942.     }
  943.  
  944.     boolean focusNext(Component base) {
  945.         synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  946.             Component target = base;
  947.             if (target != null && target.parent != null) {
  948.                 //System.out.println("FocusManager.focusNext: owner="+focusOwner);
  949.                 do {
  950.                     boolean found = false;
  951.                     Container p = target.parent;
  952.                     Component c;
  953.                     for (int i = 0; i < p.ncomponents; i++) {
  954.                         c = p.component[i];
  955.                         if (found) {
  956.                             if (assignFocus(c)) {
  957.                                 return true;
  958.                             }
  959.                             if (c instanceof Container && 
  960.                                     c.isVisible() && 
  961.                                     c.isEnabled()) {
  962.                                 if (focusForward((Container)c)) {
  963.                                     return true;
  964.                                 }
  965.                             }         
  966.                         } else if (c == target) {
  967.                             found = true;    
  968.                         }
  969.                     } 
  970.                     target = p;
  971.                 } while (target != focusRoot && target.parent != null);
  972.             }
  973.             // wrap-around
  974.             if (focusForward(focusRoot)) {
  975.                 return true;
  976.             }
  977.     
  978.             return false;        
  979.         }
  980.     }
  981.  
  982.     boolean focusPrevious() {
  983.     return focusPrevious(focusOwner);
  984.     }
  985.     
  986.     boolean focusPrevious(Component base) {
  987.         synchronized (focusRoot.getTreeLock()) { // BUGID4067845
  988.             Component target = base;
  989.             if (target != null && target.parent != null) {
  990.                 do {
  991.                     boolean found = false;
  992.                     Container p = target.parent;
  993.             if (p != null) {
  994.             Component c;
  995.             for (int i = p.ncomponents-1; i >= 0; i--) {
  996.                 c = p.component[i];
  997.                 if (found) {
  998.                 if (assignFocus(c)) {
  999.                     return true;
  1000.                 }
  1001.                 if (c instanceof Container && 
  1002.                     c.isVisible() && 
  1003.                     c.isEnabled()) {
  1004.                     if (focusBackward((Container)c)) {
  1005.                     return true;
  1006.                     }
  1007.                 }         
  1008.                 } else if (c == target) {
  1009.                 found = true;    
  1010.                 }
  1011.             } 
  1012.             }
  1013.                     target = p;
  1014.                 } while (target != null && target != focusRoot);
  1015.          
  1016.             }
  1017.         // wrap-around
  1018.             if (focusBackward(focusRoot)) {
  1019.                 return true;
  1020.             }
  1021.             return false;        
  1022.         }
  1023.     }
  1024.  
  1025.     boolean assignFocus(Component c) {
  1026.         return assignFocus(c, true);
  1027.     }
  1028.  
  1029.     synchronized boolean assignFocus(Component c, boolean requireTraversable) {
  1030.         if (c.isVisible() && c.isEnabled() &&
  1031.             (!requireTraversable || c.isFocusTraversable())) {
  1032.             //System.out.println("FocusManager.assignFocus: "+c);
  1033.             c.requestFocus();
  1034.             return true;
  1035.         }
  1036.         return false;
  1037.     }
  1038.  
  1039.     synchronized boolean focusForward(Container cont) {
  1040.         for (int i = 0; i < cont.ncomponents; i++) {
  1041.             Component c = cont.component[i];
  1042.             if (assignFocus(c)) {
  1043.                 return true;
  1044.             }
  1045.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  1046.                 if (focusForward((Container)c)) {
  1047.                     return true;
  1048.                 }
  1049.             } 
  1050.         }
  1051.         return false;
  1052.     }
  1053.  
  1054.     synchronized boolean focusBackward(Container cont) {
  1055.         for (int i = cont.ncomponents-1; i >= 0; i--) {
  1056.             Component c = cont.component[i];
  1057.             if (assignFocus(c)) {
  1058.                 return true;
  1059.             }
  1060.             if (c instanceof Container && c.isVisible() && c.isEnabled()) {
  1061.                 if (focusBackward((Container)c)) {
  1062.                     return true;
  1063.                 }
  1064.             } 
  1065.         }
  1066.         return false;
  1067.     }
  1068.  
  1069. }
  1070.